package de.hhn.mim.psb;

import static org.junit.Assert.*;

import org.junit.Test;

import Jama.Matrix;


public class CovarianceMatrixTest {

	@Test
	public void calcMatrix(){
		Vect3D[] testPoints = generateTestPoints();
		PCA3D pca = new PCA3D(testPoints);
	    Matrix covarianceMatrix = new Matrix(pca.calcCovMatrix(testPoints));	    
		Matrix correctCovarianceMatrix = new Matrix(new double[][]{{300,0,0},
																   {0,8115,4650.556},
																   {0,4650.556,2745}});
		Matrix error = correctCovarianceMatrix.minus(covarianceMatrix);
		assertTrue("Kovarianzmatrix falsch!",withinErrorMargin(error, 1e-2));
	}
	
	private boolean withinErrorMargin(Matrix error,double margin){	
		double[] rowPacked = error.getRowPackedCopy();
		for(double val : rowPacked)
			if(Math.abs(val)>=margin){
				return false;
		}
		return true;
	}
	
	private Vect3D[] generateTestPoints(){		 
	    Vect3D [] points = new Vect3D [11];
	    Vect3D [] tpoints = new Vect3D[11];
	    points[0] = new Vect3D(128,   8, 10);
	    points[1] = new Vect3D(128,  68, 10);
	    points[2] = new Vect3D(128, 128, 10);
	    points[3] = new Vect3D(128, 188, 10);
	    points[4] = new Vect3D(128, 248, 10);    
	    points[5] = new Vect3D(128, 128,  0);
	    points[6] = new Vect3D(128, 128, 20);
	    points[7] = new Vect3D(118, 128, 10);
	    points[8] = new Vect3D(138, 128, 10);
	    points[9] = new Vect3D(108, 128, 10);
	    points[10] = new Vect3D(148, 128, 10);

	    Matrix3D rx    = Matrix3D.rotationX(Math.toRadians(30));
	    Matrix3D trafo = new Matrix3D(1);
	    
	    trafo = trafo.mult(rx);    	  
	    for(int i = 0; i < points.length; i++){
	      tpoints[i] = trafo.mult(points[i]);
	    }	    
	    return tpoints;
	}
}
